package com.clp.protocol.modbus_tcp.client;

import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

@Slf4j
public class MasterContainer implements Iterable<Master> {
    private final Set<Master> allMasters;

    protected MasterContainer() {
        this.allMasters = new HashSet<>();
    }

    boolean addMasterIfNotExists(Master master) {
        if (master == null) return false;
        synchronized (allMasters) {
            if (!allMasters.contains(master)) {
                allMasters.add(master);
                log.info("向Modbus主站容器中添加新的主站：{}。\n当前容器状态：\n{}", master, this);
                return true;
            }
            log.warn("向Modbus主站容器中添加新的主站失败！可能已经存在：{}。\n当前容器状态：\n{}", master, this);
            return false;
        }
    }

    /**
     * 移除某个iec104Channel
     *
     * @param master
     * @return
     */
    boolean removeMasterIfExists(Master master) {
        if (master == null) return true;
        boolean isRemoved = false;
        synchronized (allMasters) {
            isRemoved = allMasters.remove(master);
            if (isRemoved) {
                log.info("从Modbus主站容器中移除主站：{}。\n当前容器状态：{}", master, this);
            } else {
                log.warn("从Modbus主站容器中移除主站失败！可能已经不存在：{}。\n当前容器状态：{}", master, this);
            }
        }
        return isRemoved;
    }

    boolean removeAllMasters() {
        synchronized (allMasters) {
            allMasters.clear();
            log.info("从Modbus主站容器中移除所有主站。当前个数为：{}", 0);
        }
        return true;
    }

    public Master getMaster(String remoteHost, int remotePort) {
        synchronized (allMasters) {
            for (Master inMaster : allMasters) {
                if (inMaster.remoteHost().equals(remoteHost) && inMaster.remotePort() == remotePort) {
                    return inMaster;
                }
            }
        }
        return null;
    }

    public Master getMaster(Channel channel) {
        synchronized (allMasters) {
            for (Master inMaster : allMasters) {
                if (((MasterImpl) inMaster).channel() == channel) {
                    return inMaster;
                }
            }
        }
        return null;
    }

    public boolean hasMaster(String remoteHost, int remotePort) {
        synchronized (allMasters) {
            for (Master inMaster : allMasters) {
                if (inMaster.remoteHost().equals(remoteHost) && inMaster.remotePort() == remotePort) {
                    return true;
                }
            }
        }
        return false;
    }

    boolean hasMaster(Channel channel) {
        synchronized (allMasters) {
            for (Master inMaster : allMasters) {
                if (((MasterImpl) inMaster).channel() == channel) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean isEmpty() {
        synchronized (allMasters) {
            return allMasters.isEmpty();
        }
    }

    @Override
    public Iterator<Master> iterator() {
        return new Iterator<Master>() {
            public Iterator<Master> inIterator = allMasters.iterator();
            @Override
            public boolean hasNext() {
                synchronized (allMasters) {
                    return inIterator.hasNext();
                }
            }

            @Override
            public Master next() {
                synchronized (allMasters) {
                    return inIterator.next();
                }
            }
        };
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("< 主站列表：\n");
        synchronized (allMasters) {
            int count = 1;
            for (Master inMaster : allMasters) {
                sb.append("   ").append(count++).append(" : ").append(inMaster).append("\n");
            }
        }
        sb.append(" ]\n");
        return sb.toString();
    }
}
